home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_lrm / lr7vt.src < prev    next >
Text File  |  1996-01-30  |  52KB  |  1,512 lines

  1.  
  2. --                ON-LINE Ada LANGUAGE REFERENCE MANUAL
  3. --        Developed at Nofolk State University
  4. --        Development funded by a grant from the U. S. Army
  5. --        Project ReDTEA
  6. --        Version 1.0 released December 1988
  7. --        Programmer:        Esther M. Lumsdon
  8. --        Project Director:  George C. Harrison, PhD
  9.  
  10.  
  11.  
  12. with TEXT_IO; use TEXT_IO; 
  13. with MACHINE_SPECIFIC; use MACHINE_SPECIFIC; 
  14. with LRM_TYPES; use LRM_TYPES; 
  15. with LRM_GLOBAL; use LRM_GLOBAL; 
  16. with STARLET; use STARLET; 
  17. with SMG; use SMG; 
  18.  
  19. package LRM_SMG is 
  20.  
  21.  
  22.  
  23.   ANNEX_MENU_DISPLAY   : LONGWORD_UNSIGNED; 
  24.   CHAPTER_MENU_DISPLAY : LONGWORD_UNSIGNED; 
  25.   KB_ID                : LONGWORD_UNSIGNED; 
  26.   LEFT_MOST            : NATURAL; 
  27.   -- X coordinate of where to paste virtual displays
  28.   --  dependent on whether they have borders or not.
  29.   LIMITED_BORDERS      : BOOLEAN; 
  30.   -- true if user doesn't want border on every window.
  31.  
  32.   MAIN_MENU_CHOICE     : STRING(1 .. 4); 
  33.  
  34.   MAIN_MENU_DISPLAY    : LONGWORD_UNSIGNED; 
  35.   RESULTANT_FILE       : STRING(1 .. 10); 
  36.   SIZE_COLUMNS         : LONGWORD_SIGNED; 
  37.   SIZE_ROWS            : LONGWORD_SIGNED; 
  38.   -- # of rows and columns available on user's terminal
  39.   TERM_ID              : LONGWORD_UNSIGNED; 
  40.   -- id assigned to user's terminal (pasteboard)
  41.   TEXT_SCREEN_DISPLAY  : LONGWORD_UNSIGNED; 
  42.   TOP_MOST             : NATURAL; 
  43.   -- X coordinate of where to paste virtual displays
  44.   --  dependent on whether they have borders or not.
  45.   USING_DEC_TERMINAL   : BOOLEAN; 
  46.   -- true if using DEC or compatible terminal (capable of obeying SMG$
  47.   --   VAX VMS system calls); false otherwise.
  48.   VD_2_ID              : LONGWORD_UNSIGNED; 
  49.   -- prompt and error message box
  50.  
  51.  
  52.   procedure INITIALIZE; 
  53.  
  54.   procedure WELCOME(IN_FILE_NAME : in STRING); 
  55.  
  56.   procedure DISPLAY_EXPLAIN(IN_FILE_NAME : in STRING); 
  57.  
  58.   procedure DISPLAY_MAIN_MENU(IN_FILE_NAME : in STRING); 
  59.  
  60.   procedure SELECT_FROM_MAIN_MENU(MAIN_MENU_CHOICE : out STRING); 
  61.  
  62.   procedure SCROLL_TEXT(IN_FILE_NAME : in STRING; 
  63.                         SAVE_TITLE   : in STRING; 
  64.                         SAVE_FILE    : in out FILE_TYPE); 
  65.  
  66.   procedure DO_CHAPTER_MENU(SAVE_FILE : in out FILE_TYPE); 
  67.  
  68.   procedure DO_ANNEX_MENU(SAVE_FILE : in out FILE_TYPE); 
  69.  
  70.   procedure CREDITS(SAVE_FILE : in out FILE_TYPE); 
  71.  
  72.   procedure TERMINATE_LRM; 
  73.  
  74.  
  75. end LRM_SMG; 
  76.  
  77. -----------------------------------------------------------------
  78.  
  79. with TEXT_IO; use TEXT_IO; 
  80. with LRM_TYPES; use LRM_TYPES; 
  81. with LRM_GLOBAL; use LRM_GLOBAL; 
  82. with STARLET; use STARLET; 
  83. with SMG; use SMG; 
  84. with INT_IO; use INT_IO; 
  85.  
  86. package body LRM_SMG is 
  87.  
  88.  
  89.  
  90.  
  91.   procedure DISPLAY_MENU(IN_FILE_NAME : in STRING; 
  92.                          DISPLAY_ID   : in LONGWORD_UNSIGNED) is 
  93.  
  94.  
  95.  
  96.   -- read menu text from file, and put entire file on screen.
  97.  
  98.     EMPTY_STRING_80 : STRING(1 .. 80); 
  99.     LAST_CHAR       : NATURAL := 0; 
  100.     READ_IN_FILE    : FILE_TYPE; 
  101.     READ_IN_LINE    : STRING(1 .. 80); 
  102.  
  103.  
  104.   begin
  105.     for I in 1 .. 80 loop
  106.       EMPTY_STRING_80 := (others => ' '); 
  107.     end loop; 
  108.  
  109.     OPEN(READ_IN_FILE, IN_FILE, IN_FILE_NAME); 
  110.     while not END_OF_FILE(READ_IN_FILE) loop
  111.       READ_IN_LINE := EMPTY_STRING_80; 
  112.       GET_LINE(READ_IN_FILE, READ_IN_LINE, LAST_CHAR); 
  113.       PUT_LINE(DISPLAY_ID => DISPLAY_ID, TEXT => READ_IN_LINE); 
  114.     end loop; 
  115.  
  116.   end DISPLAY_MENU; 
  117.  
  118.  
  119. ------------------------------------------------------------------------------
  120.  
  121.  
  122.   procedure DISPLAY_CHAPTER_MENU(IN_FILE_NAME : in STRING) is 
  123.  
  124.  
  125.  
  126.   -- read menu text from file, and put entire file on screen.
  127.  
  128.     EMPTY_STRING_80 : STRING(1 .. 80); 
  129.     LAST_CHAR       : NATURAL := 0; 
  130.     READ_IN_FILE    : FILE_TYPE; 
  131.     READ_IN_LINE    : STRING(1 .. 80); 
  132.  
  133.  
  134.   begin
  135.     EMPTY_STRING_80 := (others => ' '); 
  136.  
  137.     OPEN(READ_IN_FILE, IN_FILE, IN_FILE_NAME); 
  138.     SET_CURSOR_ABS(CHAPTER_MENU_DISPLAY, 3, 1); 
  139.  
  140.     while not END_OF_FILE(READ_IN_FILE) loop
  141.       READ_IN_LINE := EMPTY_STRING_80; 
  142.       GET_LINE(READ_IN_FILE, READ_IN_LINE, LAST_CHAR); 
  143.       PUT_LINE(DISPLAY_ID => CHAPTER_MENU_DISPLAY, TEXT => READ_IN_LINE); 
  144.  
  145.     -- VMS 5.0  put_line (display_id => chapter_menu_display, text
  146.     --  => read_in_line, flags => smg$m_wrap_word);
  147.     end loop; 
  148.  
  149.   end DISPLAY_CHAPTER_MENU; 
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156. ------------------------------------------------------------------------------
  157.   procedure INITIALIZE is 
  158.  
  159.   --    Initialization for on-line Ada Language Reference Manual
  160.   --      using SMG$ virtual terminal driver
  161.   --
  162.   --
  163.   --LOGIC:
  164.   --
  165.   -- Decide terminal category
  166.   -- Prompt user for value of limited_borders
  167.   -- create pasteboard
  168.   -- create bordered box for prompts ( 1 rows x 78 columns @20,2), the
  169.   --     annex_menu_display, chapter_menu_display, main_menu_display;
  170.   --     most of these are 18 rows x 78 columns, paste @2,2. 
  171.   --     
  172.   -- create virtual keyboard for user input
  173.   -- attach virtual keyboard to user device
  174.   --
  175.  
  176.  
  177.     BORDER_CHOICE : CHARACTER := 'y'; 
  178.     OD            : CHAR_STRING(1 .. 10);  -- output device
  179.     PSF           : MASK_LONGWORD;  -- Preserve Screen Flag (in SMG$)
  180.  
  181.   ----------------------------------------------------------------------------
  182.     procedure DECIDE_TERM_CATEGORY(USING_DEC_TERMINAL : out BOOLEAN) is 
  183.  
  184.       CHOSE_TERMINAL_CATEGORY : BOOLEAN; 
  185.       TERM_CATEGORY           : CHARACTER; 
  186.  
  187.  
  188.     begin
  189.  
  190.       loop
  191.         CLS; 
  192.         PUT_LINE("  The following terminals are available for your use at NSU:")
  193.           ; 
  194.         PUT_LINE("Category A terminals:"); 
  195.         PUT_LINE("    VISUAL brand terminals"); 
  196.         PUT_LINE("    TeleVideo brand terminals"); 
  197.         PUT_LINE("    DEC terminals"); 
  198.         NEW_LINE; 
  199.         PUT_LINE("Category B terminals:"); 
  200.         PUT_LINE("    ADM brand terminals"); 
  201.         PUT_LINE("    Adds-Viewpoint terminals"); 
  202.         PUT_LINE("    Hazeltine brand terminals"); 
  203.         NEW_LINE(2); 
  204.         PUT(
  205.           "Please enter A or B for the category of terminal that you are using: "
  206.           ); 
  207.         GET(TERM_CATEGORY); 
  208.         CHOSE_TERMINAL_CATEGORY := TRUE; 
  209.         case TERM_CATEGORY is 
  210.           when 'A' | ASCII.LC_A => 
  211.             USING_DEC_TERMINAL := TRUE; 
  212.           when 'B' | ASCII.LC_B => 
  213.             USING_DEC_TERMINAL := FALSE; 
  214.           when others => 
  215.             CHOSE_TERMINAL_CATEGORY := FALSE; 
  216.         end case; 
  217.         exit when CHOSE_TERMINAL_CATEGORY; 
  218.       end loop; 
  219.  
  220.     end DECIDE_TERM_CATEGORY; 
  221.  
  222.     -----------------------------------------------------------------
  223.  
  224.   begin
  225.  
  226.     -- create annex_menu_display, chapter_menu_display, main_menu_display,
  227.     -- text_screen_display
  228.     CLS; 
  229.     USING_DEC_TERMINAL := TRUE; 
  230.     if USING_DEC_TERMINAL then 
  231.       NEW_LINE(2); 
  232.       PUT_LINE("Do you want windows with borders, or without borders?"); 
  233.       PUT(
  234.         "If you are accessing this system at slower than 4800 baud, your screen"
  235.         ); 
  236.       NEW_LINE; 
  237.       PUT_LINE("  will update much faster without borders."); 
  238.       NEW_LINE; 
  239.       PUT("Do you want borders (y/n) ? "); 
  240.       GET(BORDER_CHOICE); 
  241.       if (BORDER_CHOICE = 'n' or BORDER_CHOICE = 'N') then 
  242.         LIMITED_BORDERS := TRUE; 
  243.         SCREEN_HEIGHT := 19; 
  244.       else 
  245.         LIMITED_BORDERS := FALSE; 
  246.         SCREEN_WIDTH := SCREEN_WIDTH - 2; 
  247.         SCREEN_HEIGHT := 18; 
  248.       end if; 
  249.       OD := "SYS$OUTPUT"; 
  250.  
  251.       --  set psf=0
  252.       PSF := 0; 
  253.       CREATE_PASTEBOARD(TERM_ID, OD, SIZE_ROWS, SIZE_COLUMNS, PSF); 
  254.       CREATE_VIRTUAL_KEYBOARD(NEW_KEYBOARD_ID => KB_ID, RESULTANT_FILESPEC => 
  255.         RESULTANT_FILE); 
  256.       if LIMITED_BORDERS then 
  257.         TOP_MOST := 1; 
  258.         LEFT_MOST := 1; 
  259.       else 
  260.         TOP_MOST := 2; 
  261.         LEFT_MOST := 2; 
  262.       end if; 
  263.       if LIMITED_BORDERS then 
  264.         CREATE_VIRTUAL_DISPLAY(NUM_ROWS => 25, NUM_COLUMNS => 80, NEW_DISPLAY_ID
  265.           => CHAPTER_MENU_DISPLAY); 
  266.       else 
  267.         CREATE_VIRTUAL_DISPLAY(22, 78, CHAPTER_MENU_DISPLAY, SMG_M_BORDER); 
  268.       end if; 
  269.       if LIMITED_BORDERS then 
  270.         CREATE_VIRTUAL_DISPLAY(NUM_ROWS => 19, NUM_COLUMNS => 80, NEW_DISPLAY_ID
  271.           => ANNEX_MENU_DISPLAY); 
  272.       else 
  273.  
  274. --        CREATE_VIRTUAL_DISPLAY_ATTRIBUTES(19, 78, ANNEX_MENU_DISPLAY, 
  275.         --          SMG_M_BORDER, SMG_M_BOLD); 
  276.         CREATE_VIRTUAL_DISPLAY(19, 78, ANNEX_MENU_DISPLAY, SMG_M_BORDER); 
  277.       end if; 
  278.       DISPLAY_MENU(MENU_ANNEX_FILE_NAME, ANNEX_MENU_DISPLAY); 
  279.       DISPLAY_CHAPTER_MENU(MENU_CHAPTER_FILE_NAME); 
  280.  
  281.       if LIMITED_BORDERS then 
  282.         CREATE_VIRTUAL_DISPLAY(NUM_ROWS => 19, NUM_COLUMNS => 80, NEW_DISPLAY_ID
  283.           => MAIN_MENU_DISPLAY); 
  284.       else 
  285.  
  286.         --        CREATE_VIRTUAL_DISPLAY_ATTRIBUTES(19, 78, MAIN_MENU_DISPLAY, 
  287.         --          SMG_M_BORDER, SMG_M_BOLD); 
  288.         CREATE_VIRTUAL_DISPLAY(19, 78, MAIN_MENU_DISPLAY, SMG_M_BORDER); 
  289.       end if; 
  290.       if LIMITED_BORDERS then 
  291.         CREATE_VIRTUAL_DISPLAY(NUM_ROWS => 19, NUM_COLUMNS => 80, NEW_DISPLAY_ID
  292.           => TEXT_SCREEN_DISPLAY); 
  293.       else 
  294.  
  295. --        CREATE_VIRTUAL_DISPLAY_ATTRIBUTES(19, 78, TEXT_SCREEN_DISPLAY, 
  296.         --          SMG_M_BORDER, SMG_M_BOLD); 
  297.         CREATE_VIRTUAL_DISPLAY(19, 78, TEXT_SCREEN_DISPLAY, SMG_M_BOLD); 
  298.       end if; 
  299.  
  300.  
  301.       CREATE_VIRTUAL_DISPLAY(1, 78, VD_2_ID, SMG_M_BORDER, SMG_M_BOLD); 
  302.  
  303.     end if; 
  304.  
  305.   end INITIALIZE; 
  306.  
  307.  
  308.  
  309.  
  310. ------------------------------------------------------------------------------
  311.  
  312.  
  313.   procedure TERMINATE_LRM is 
  314.   --TERM_ID : in LONGWORD_UNSIGNED; 
  315.   --                          VD_2_ID : in LONGWORD_UNSIGNED
  316.  
  317.  
  318.  
  319.   --  LOGIC:
  320.   --  delete all virtual displays (pop the stack)
  321.   --  delete the pasteboard
  322.  
  323.  
  324.   begin
  325.     POP_VIRTUAL_DISPLAY(VD_2_ID, TERM_ID); 
  326.     POP_VIRTUAL_DISPLAY(MAIN_MENU_DISPLAY, TERM_ID); 
  327.     if IS_OPEN(SAVE_FILE) then 
  328.       CLOSE(SAVE_FILE); 
  329.     end if; 
  330.     CLS; 
  331.     NEW_LINE(2); 
  332.     PUT_LINE("Thank you for using the Ada Language Reference Manual Reader."); 
  333.   end TERMINATE_LRM; 
  334.  
  335.  
  336.  
  337.  
  338. ------------------------------------------------------------------------------
  339.  
  340.   procedure DISPLAY_MAIN_MENU(IN_FILE_NAME : in STRING) is 
  341.  
  342.  
  343.   -- read menu text from file, and put entire file on screen.
  344.  
  345.     EMPTY_STRING_80 : STRING(1 .. 80); 
  346.     LAST_CHAR       : NATURAL := 0; 
  347.     READ_IN_FILE    : FILE_TYPE; 
  348.     READ_IN_LINE    : STRING(1 .. 80); 
  349.  
  350.  
  351.   begin
  352.     EMPTY_STRING_80 := (others => ' '); 
  353.     PASTE_VIRTUAL_DISPLAY(VD_2_ID, TERM_ID, 22, 2); 
  354.     PASTE_VIRTUAL_DISPLAY(MAIN_MENU_DISPLAY, TERM_ID, 2, 2); 
  355.  
  356.     OPEN(READ_IN_FILE, IN_FILE, IN_FILE_NAME); 
  357.     while not END_OF_FILE(READ_IN_FILE) loop
  358.       READ_IN_LINE := EMPTY_STRING_80; 
  359.       GET_LINE(READ_IN_FILE, READ_IN_LINE, LAST_CHAR); 
  360.       PUT_LINE(DISPLAY_ID => MAIN_MENU_DISPLAY, TEXT => READ_IN_LINE); 
  361.     end loop; 
  362.  
  363.   end DISPLAY_MAIN_MENU; 
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.   ---------------------------------------------------------------------------
  371.  
  372. ------------------------------------------------------------------------------
  373.  
  374.   procedure SCROLL_TEXT(IN_FILE_NAME : in STRING; 
  375.                         SAVE_TITLE   : in STRING; 
  376.                         SAVE_FILE    : in out FILE_TYPE) is 
  377.  
  378.  
  379.  
  380.   -- scroll text file on the screen, 19 lines at a time
  381.  
  382.     type COMMAND is (CONTINUE, DISPLAY_AGAIN, EXIT_COMMAND, SAVE, NOTHING); 
  383.  
  384.     BLANK_COUNT      : NATURAL := 0; 
  385.     CURRENT_LINE     : NATURAL := 0; 
  386.     EXIT_NOW         : BOOLEAN := FALSE; 
  387.     GOOD_ANSWER      : BOOLEAN; 
  388.     LAST_CHAR        : NATURAL := 0; 
  389.     LAST_COMMAND     : COMMAND := NOTHING; 
  390.     READ_IN_FILE     : FILE_TYPE; 
  391.     READ_IN_LINE     : STRING(1 .. 156); 
  392.     EMPTY_STRING_156 : STRING(1 .. 156); 
  393.     RECD_STR_LEN     : WORD_UNSIGNED; 
  394.     SAVING           : BOOLEAN := FALSE; 
  395.     TERM_CODE        : WORD_UNSIGNED; 
  396.     WAIT_STR         : STRING(1 .. 10); 
  397.     LINE_COUNT       : NATURAL := 0; 
  398.  
  399.   begin
  400.     EMPTY_STRING_156 := (others => ' '); 
  401.  
  402.     OPEN(READ_IN_FILE, IN_FILE, IN_FILE_NAME); 
  403.     ERASE_DISPLAY(TEXT_SCREEN_DISPLAY); 
  404.     PASTE_VIRTUAL_DISPLAY(TEXT_SCREEN_DISPLAY, TERM_ID, 2, 2); 
  405.  
  406.     --    PASTE_VIRTUAL_DISPLAY(VD_2_ID, TERM_ID, 22, 2); 
  407.     while not EXIT_NOW loop
  408.       LINE_COUNT := 0; 
  409.       if LAST_COMMAND /= SAVE then 
  410.  
  411.         while ((not END_OF_FILE(READ_IN_FILE)) and (LINE_COUNT < SCREEN_HEIGHT))
  412.           loop
  413.           READ_IN_LINE := EMPTY_STRING_156; 
  414.           GET_LINE(READ_IN_FILE, READ_IN_LINE, LAST_CHAR); 
  415.  
  416.           --          don't need a SKIP_LINE statement.
  417.           --          SKIP_LINE (READ_IN_FILE);
  418.           if LAST_CHAR = 0 then 
  419.             BLANK_COUNT := BLANK_COUNT + 1; 
  420.           else 
  421.             BLANK_COUNT := 0; 
  422.           end if; 
  423.           if BLANK_COUNT < 3 then 
  424.             if LAST_CHAR > SCREEN_WIDTH then 
  425.               PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => READ_IN_LINE(1
  426.                 .. SCREEN_WIDTH)); 
  427.               PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => READ_IN_LINE(
  428.                 SCREEN_WIDTH + 1 .. LAST_CHAR)); 
  429.               LINE_COUNT := LINE_COUNT + 2; 
  430.             else 
  431.               PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => READ_IN_LINE(1
  432.                 .. LAST_CHAR)); 
  433.               LINE_COUNT := LINE_COUNT + 1; 
  434.             end if; 
  435.           end if; 
  436.           if SAVING then 
  437.             PUT_LINE(SAVE_FILE, READ_IN_LINE(1 .. LAST_CHAR)); 
  438.           end if; 
  439.           CURRENT_LINE := CURRENT_LINE + 1; 
  440.         end loop; 
  441.  
  442.       end if; 
  443.  
  444.       GOOD_ANSWER := FALSE; 
  445.       while not GOOD_ANSWER loop
  446.         GOOD_ANSWER := TRUE; 
  447.         if END_OF_FILE(READ_IN_FILE) then 
  448.           if SAVING then 
  449.             NEW_LINE(SAVE_FILE, 3); 
  450.           end if; 
  451.           READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => WAIT_STR, TIMEOUT
  452.             => 500, PROMPT_STRING => "     E[xit]   S[ave]   D[isplay again] "
  453.             , MAX_LENGTH => 1, RECEIVED_STRING_LENGTH => RECD_STR_LEN, 
  454.             TERMINATOR_CODE => TERM_CODE, DISPLAY_ID => VD_2_ID); 
  455.         else 
  456.           READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => WAIT_STR, TIMEOUT
  457.             => 500, PROMPT_STRING => 
  458.             "     E[xit]   C[ontinue]   S[ave]   D[isplay again] ", MAX_LENGTH
  459.             => 1, RECEIVED_STRING_LENGTH => RECD_STR_LEN, TERMINATOR_CODE => 
  460.             TERM_CODE, DISPLAY_ID => VD_2_ID); 
  461.         end if; 
  462.         PUT_LINE(DISPLAY_ID => VD_2_ID, TEXT => "               "); 
  463.         case WAIT_STR(1) is 
  464.           when 'E' | ASCII.LC_E => 
  465.             LAST_COMMAND := EXIT_COMMAND; 
  466.             EXIT_NOW := TRUE; 
  467.             exit; 
  468.           when 'S' | ASCII.LC_S => 
  469.             LAST_COMMAND := SAVE; 
  470.             if not SAVING then 
  471.               if not IS_OPEN(SAVE_FILE) then 
  472.                 CREATE(SAVE_FILE, OUT_FILE, LRM_READER_SAVE_FILE_NAME); 
  473.               end if; 
  474.               PUT_LINE(SAVE_FILE, 
  475.                 "Reference from Ada Language Reference Manual:"); 
  476.               PUT_LINE(SAVE_FILE, SAVE_TITLE); 
  477.  
  478.               -- write title of what is being saved to save_file.
  479.               NEW_LINE(SAVE_FILE, 2); 
  480.               SAVING := TRUE; 
  481.               if CURRENT_LINE > 1 then 
  482.                 RESET(READ_IN_FILE, IN_FILE); 
  483.                 for I in 1 .. CURRENT_LINE loop
  484.                   GET_LINE(READ_IN_FILE, READ_IN_LINE, LAST_CHAR); 
  485.                   PUT_LINE(SAVE_FILE, READ_IN_LINE(1 .. LAST_CHAR)); 
  486.                 end loop; 
  487.               end if; 
  488.             end if; 
  489.           when 'D' | ASCII.LC_D => 
  490.             LAST_COMMAND := DISPLAY_AGAIN; 
  491.             RESET(READ_IN_FILE, IN_FILE); 
  492.             CURRENT_LINE := 0; 
  493.             PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => "      "); 
  494.           when 'C' | ASCII.LC_C => 
  495.             LAST_COMMAND := CONTINUE; 
  496.  
  497.           -- continue the display
  498.           when others => 
  499.             GOOD_ANSWER := FALSE; 
  500.         end case; 
  501.  
  502.       -- while not good_answer loop
  503.       end loop; 
  504.  
  505.     --  while not exit_now loop
  506.     end loop; 
  507.  
  508.  
  509.     if SAVING then 
  510.       NEW_LINE(SAVE_FILE, 3); 
  511.     end if; 
  512.     CLOSE(READ_IN_FILE); 
  513.     UNPASTE_VIRTUAL_DISPLAY(TEXT_SCREEN_DISPLAY, TERM_ID); 
  514.  
  515.   --    UNPASTE_VIRTUAL_DISPLAY(VD_2_ID, TERM_ID); 
  516.   end SCROLL_TEXT; 
  517.  
  518.  
  519.  
  520.  
  521. ------------------------------------------------------------------------------
  522.  
  523.   procedure WELCOME(IN_FILE_NAME : in STRING) is 
  524.  
  525.  
  526.  
  527.   --  display welcome message for 3 seconds
  528.  
  529.     KEY_TO_CONTINUE         : CHARACTER; 
  530.     LAST_CHAR               : NATURAL := 0; 
  531.     LINE_COUNT              : NATURAL; 
  532.     RECD_STR_LEN, TERM_CODE : WORD_UNSIGNED; 
  533.     WAIT_STR                : STRING(1 .. 10); 
  534.     WELCOME_FILE            : FILE_TYPE; 
  535.     -- menu.welcome_msg is 19 lines x 80 cols
  536.     WELCOME_ID              : LONGWORD_UNSIGNED; 
  537.     WELCOME_LINE            : STRING(1 .. 80); 
  538.  
  539.  
  540.  
  541.     -- the widest size virt disp that can have visible borders on a
  542.     -- terminal is 78 columns. this must be displayed at column 2.
  543.  
  544.  
  545.  
  546.   begin
  547.     OPEN(WELCOME_FILE, IN_FILE, IN_FILE_NAME); 
  548.  
  549.     --"menu.welcome_msg"); 
  550.     GET_LINE(WELCOME_FILE, WELCOME_LINE, LAST_CHAR); 
  551.     if LIMITED_BORDERS then 
  552.       CREATE_VIRTUAL_DISPLAY(NUM_ROWS => 22, NUM_COLUMNS => 78, NEW_DISPLAY_ID
  553.         => WELCOME_ID, VIDEO_ATTRIBUTES => SMG_M_BOLD); 
  554.     else 
  555.       CREATE_VIRTUAL_DISPLAY(22, 78, WELCOME_ID, SMG_M_BORDER); 
  556.  
  557.     -- was 19, 78   15, 74
  558.     end if; 
  559.     PASTE_VIRTUAL_DISPLAY(WELCOME_ID, TERM_ID, 2, 2); 
  560.  
  561.     --was2,2  4,4
  562.     if not LIMITED_BORDERS then 
  563.       LABEL_BORDER(WELCOME_ID, "WELCOME", 0); 
  564.     end if; 
  565.  
  566.     while not END_OF_FILE(WELCOME_FILE) loop
  567.       GET_LINE(WELCOME_FILE, WELCOME_LINE, LAST_CHAR); 
  568.       SKIP_LINE(WELCOME_FILE); 
  569.       PUT_LINE(DISPLAY_ID => WELCOME_ID, TEXT => WELCOME_LINE); 
  570.     end loop; 
  571.  
  572.     READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => WAIT_STR, MAX_LENGTH => 1
  573.       , TIMEOUT => 10, RECEIVED_STRING_LENGTH => RECD_STR_LEN, TERMINATOR_CODE
  574.       => TERM_CODE, DISPLAY_ID => WELCOME_ID); 
  575.     POP_VIRTUAL_DISPLAY(WELCOME_ID, TERM_ID); 
  576.  
  577.     CLOSE(WELCOME_FILE); 
  578.   end WELCOME; 
  579.  
  580.  
  581.  
  582.  
  583.   ---------------------------------------------------------------------------
  584.  
  585.   procedure CREDITS(SAVE_FILE : in out FILE_TYPE) is 
  586.  
  587.  
  588.  
  589.   -- scroll credit on the screen
  590.  
  591.  
  592.   begin
  593.     SCROLL_TEXT(CREDITS_FILE_NAME, "Credits          ", SAVE_FILE); 
  594.  
  595.   end CREDITS; 
  596.  
  597. ------------------------------------------------------------------------------
  598.  
  599.   procedure DISPLAY_EXPLAIN(IN_FILE_NAME : in STRING) is 
  600.  
  601.  
  602.  
  603.   -- scroll text file on the screen, 19 lines at a time
  604.  
  605.     GOOD_ANSWER     : BOOLEAN; 
  606.     LAST_CHAR       : NATURAL := 0; 
  607.     READ_IN_FILE    : FILE_TYPE; 
  608.     READ_IN_LINE    : STRING(1 .. 80); 
  609.     EMPTY_STRING_80 : STRING(1 .. 80); 
  610.     RECD_STR_LEN    : WORD_UNSIGNED; 
  611.     TERM_CODE       : WORD_UNSIGNED; 
  612.     WAIT_STR        : STRING(1 .. 10); 
  613.     LINE_COUNT      : NATURAL := 0; 
  614.  
  615.   begin
  616.     EMPTY_STRING_80 := (others => ' '); 
  617.     OPEN(READ_IN_FILE, IN_FILE, IN_FILE_NAME); 
  618.     PASTE_VIRTUAL_DISPLAY(TEXT_SCREEN_DISPLAY, TERM_ID, 2, 2); 
  619.     PASTE_VIRTUAL_DISPLAY(VD_2_ID, TERM_ID, 22, 2); 
  620.  
  621.     while not (END_OF_FILE(READ_IN_FILE)) loop
  622.  
  623.       LINE_COUNT := 0; 
  624.  
  625.       while (LINE_COUNT < (SCREEN_HEIGHT - 2)) loop
  626.         READ_IN_LINE := EMPTY_STRING_80; 
  627.         if not END_OF_FILE(READ_IN_FILE) then 
  628.           GET_LINE(READ_IN_FILE, READ_IN_LINE, LAST_CHAR); 
  629.  
  630.           --          don't need a SKIP_LINE statement.
  631.           --          SKIP_LINE (READ_IN_FILE);
  632.           if LAST_CHAR > SCREEN_WIDTH then 
  633.             PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => READ_IN_LINE(1
  634.               .. SCREEN_WIDTH)); 
  635.             PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => READ_IN_LINE(
  636.               SCREEN_WIDTH + 1 .. LAST_CHAR)); 
  637.             LINE_COUNT := LINE_COUNT + 2; 
  638.           else 
  639.             PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => READ_IN_LINE); 
  640.             LINE_COUNT := LINE_COUNT + 1; 
  641.           end if; 
  642.         else 
  643.           exit; 
  644.         end if; 
  645.       end loop; 
  646.       READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => WAIT_STR, TIMEOUT => 5
  647.         , PROMPT_STRING => "     C[ontinue] ", MAX_LENGTH => 1, 
  648.         RECEIVED_STRING_LENGTH => RECD_STR_LEN, TERMINATOR_CODE => TERM_CODE, 
  649.         DISPLAY_ID => VD_2_ID); 
  650.       PUT_LINE(DISPLAY_ID => VD_2_ID, TEXT => "               "); 
  651.  
  652.     --  while not eof(read_in_file) loop
  653.     end loop; 
  654.  
  655.     CLOSE(READ_IN_FILE); 
  656.     UNPASTE_VIRTUAL_DISPLAY(TEXT_SCREEN_DISPLAY, TERM_ID); 
  657.     UNPASTE_VIRTUAL_DISPLAY(VD_2_ID, TERM_ID); 
  658.  
  659.  
  660.   end DISPLAY_EXPLAIN; 
  661.  
  662.  
  663.  
  664.  
  665.  
  666. ------------------------------------------------------------------------------
  667.  
  668.   procedure SELECT_FROM_MAIN_MENU(MAIN_MENU_CHOICE : out STRING) is 
  669.  
  670.     MAIN_MENU_CHOICE_LEN : WORD_UNSIGNED; 
  671.     TERM_CODE            : WORD_UNSIGNED; 
  672.  
  673.   begin
  674.     PUT_LINE(DISPLAY_ID => VD_2_ID, TEXT => "                        "); 
  675.     READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => MAIN_MENU_CHOICE, 
  676.       MAX_LENGTH => 1, RECEIVED_STRING_LENGTH => MAIN_MENU_CHOICE_LEN, 
  677.       PROMPT_STRING => "Choose from 1 - 7, please: ", TERMINATOR_CODE => 
  678.       TERM_CODE, DISPLAY_ID => VD_2_ID); 
  679.     PUT_LINE(DISPLAY_ID => VD_2_ID, TEXT => "                        "); 
  680.   end SELECT_FROM_MAIN_MENU; 
  681.  
  682. ------------------------------------------------------------------------------
  683.  
  684.   procedure DO_ANNEX_MENU(SAVE_FILE : in out FILE_TYPE) is 
  685.  
  686.     ANNEX_MENU_CHOICE     : STRING(1 .. 2); 
  687.     ANNEX_MENU_CHOICE_LEN : WORD_UNSIGNED; 
  688.     TERM_CODE             : WORD_UNSIGNED; 
  689.  
  690.  
  691.   begin
  692.     PASTE_VIRTUAL_DISPLAY(ANNEX_MENU_DISPLAY, TERM_ID, 2, 2); 
  693.     loop
  694.       READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => ANNEX_MENU_CHOICE, 
  695.         MAX_LENGTH => 1, RECEIVED_STRING_LENGTH => ANNEX_MENU_CHOICE_LEN, 
  696.         PROMPT_STRING => "Choose from A - F or Q, please: ", TERMINATOR_CODE => 
  697.         TERM_CODE, DISPLAY_ID => VD_2_ID); 
  698.       PUT_LINE(DISPLAY_ID => VD_2_ID, TEXT => "              "); 
  699.       case ANNEX_MENU_CHOICE(1) is 
  700.         when 'A' | 'a' => 
  701.           SCROLL_TEXT(LRM_FILE_NAME_PREFIX(1 .. LRM_FILE_NAME_PREFIX_LENGTH) & 
  702.             "chapa.doc", "Annex A          ", SAVE_FILE); 
  703.         when 'B' | 'b' => 
  704.           SCROLL_TEXT(LRM_FILE_NAME_PREFIX(1 .. LRM_FILE_NAME_PREFIX_LENGTH) & 
  705.             "chapb.doc", "Annex B          ", SAVE_FILE); 
  706.         when 'C' | 'c' => 
  707.           SCROLL_TEXT(LRM_FILE_NAME_PREFIX(1 .. LRM_FILE_NAME_PREFIX_LENGTH) & 
  708.             "chapc.doc", "Annex C          ", SAVE_FILE); 
  709.         when 'D' | 'd' => 
  710.           SCROLL_TEXT(LRM_FILE_NAME_PREFIX(1 .. LRM_FILE_NAME_PREFIX_LENGTH) & 
  711.             "chapd.doc", "Annex D          ", SAVE_FILE); 
  712.         when 'E' | 'e' => 
  713.           SCROLL_TEXT(LRM_FILE_NAME_PREFIX(1 .. LRM_FILE_NAME_PREFIX_LENGTH) & 
  714.             "chape.doc", "Annex E          ", SAVE_FILE); 
  715.         when 'F' | 'f' => 
  716.           SCROLL_TEXT(LRM_FILE_NAME_PREFIX(1 .. LRM_FILE_NAME_PREFIX_LENGTH) & 
  717.             "chapf.doc", "Annex F          ", SAVE_FILE); 
  718.         when 'Q' | 'q' => 
  719.           UNPASTE_VIRTUAL_DISPLAY(ANNEX_MENU_DISPLAY, TERM_ID); 
  720.           exit; 
  721.         when others => 
  722.           null; 
  723.       end case; 
  724.     end loop; 
  725.  
  726.  
  727.   end DO_ANNEX_MENU; 
  728.  
  729.  
  730.  
  731.   ---------------------------------------------------------------------------
  732.  
  733. ------------------------------------------------------------------------------
  734.  
  735.  
  736.   procedure SCROLL_CHAP(IN_FILE_NAME       : in STRING; 
  737.                         FIRST_LINE         : in NATURAL; 
  738.                         LAST_LINE          : in NATURAL; 
  739.                         SAVE_FILE          : in out FILE_TYPE; 
  740.                         UNTIL_EOF          : in BOOLEAN; 
  741.                         CITATION_REQUESTED : in STRING) is 
  742.  
  743.  
  744.  
  745.  
  746.   -- scroll text file on the screen, 19 lines at a time
  747.  
  748.     type COMMAND is (CONTINUE, DISPLAY_AGAIN, EXIT_COMMAND, SAVE, NOTHING); 
  749.  
  750.     AT_LAST_LINE     : BOOLEAN := FALSE; 
  751.     BLANK_30         : STRING(1 .. 30) := (others => ' '); 
  752.     BLANK_COUNT      : NATURAL := 0; 
  753.     EXIT_NOW         : BOOLEAN := FALSE; 
  754.     GOOD_ANSWER      : BOOLEAN; 
  755.     LAST_CHAR        : NATURAL := 0; 
  756.     LAST_COMMAND     : COMMAND := NOTHING; 
  757.     READ_IN_FILE     : FILE_TYPE; 
  758.     READ_IN_LINE     : STRING(1 .. 156); 
  759.     EMPTY_STRING_156 : STRING(1 .. 156); 
  760.     RECD_STR_LEN     : WORD_UNSIGNED; 
  761.     SAVING           : BOOLEAN := FALSE; 
  762.     TERM_CODE        : WORD_UNSIGNED; 
  763.     WAIT_STR         : STRING(1 .. 10); 
  764.     LINE_COUNT       : NATURAL := 0; 
  765.     CURRENT_LINE     : NATURAL := 0; 
  766.  
  767.  
  768.     procedure GOTO_FIRST_LINE(FIRST_LINE : in NATURAL) is 
  769.       READ_IN_LINE : STRING(1 .. 156); 
  770.       LAST_CHAR    : NATURAL; 
  771.  
  772.     begin
  773.       RESET(READ_IN_FILE, IN_FILE); 
  774.       for I in 1 .. (FIRST_LINE - 1) loop
  775.         GET_LINE(READ_IN_FILE, READ_IN_LINE, LAST_CHAR); 
  776.       end loop; 
  777.     end GOTO_FIRST_LINE; 
  778.  
  779.  
  780.   begin
  781.  
  782.     ERASE_DISPLAY(TEXT_SCREEN_DISPLAY); 
  783.     EMPTY_STRING_156 := (others => ' '); 
  784.     OPEN(READ_IN_FILE, IN_FILE, IN_FILE_NAME); 
  785.     PASTE_VIRTUAL_DISPLAY(TEXT_SCREEN_DISPLAY, TERM_ID, 2, 2); 
  786.  
  787.     REPASTE_VIRTUAL_DISPLAY(VD_2_ID, TERM_ID, 23, 2); 
  788.  
  789.     -- was 22, 2
  790.     GOTO_FIRST_LINE(FIRST_LINE); 
  791.     CURRENT_LINE := FIRST_LINE - 1; 
  792.     while not EXIT_NOW loop
  793.       LINE_COUNT := 0; 
  794.  
  795.       if LAST_COMMAND /= SAVE then 
  796.  
  797.         if UNTIL_EOF then 
  798.  
  799.           while ((not END_OF_FILE(READ_IN_FILE)) and (LINE_COUNT <= 18)) loop
  800.             READ_IN_LINE := EMPTY_STRING_156; 
  801.             GET_LINE(READ_IN_FILE, READ_IN_LINE, LAST_CHAR); 
  802.             if LAST_CHAR = 0 then 
  803.               BLANK_COUNT := BLANK_COUNT + 1; 
  804.             else 
  805.               BLANK_COUNT := 0; 
  806.             end if; 
  807.             if SAVING then 
  808.               PUT_LINE(SAVE_FILE, READ_IN_LINE(1 .. LAST_CHAR)); 
  809.             end if; 
  810.             CURRENT_LINE := CURRENT_LINE + 1; 
  811.  
  812.             --          don't need a SKIP_LINE statement.
  813.             --          SKIP_LINE (READ_IN_FILE);
  814.             if BLANK_COUNT < 3 then 
  815.               if LAST_CHAR > SCREEN_WIDTH then 
  816.                 LINE_COUNT := LINE_COUNT + 2; 
  817.                 PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => READ_IN_LINE
  818.                   (1 .. SCREEN_WIDTH)); 
  819.                 PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => READ_IN_LINE
  820.                   (SCREEN_WIDTH + 1 .. LAST_CHAR)); 
  821.               else 
  822.                 PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => READ_IN_LINE
  823.                   (1 .. LAST_CHAR)); 
  824.                 LINE_COUNT := LINE_COUNT + 1; 
  825.               end if; 
  826.             end if; 
  827.           end loop; 
  828.  
  829.         else 
  830.  
  831.           while ((CURRENT_LINE < (LAST_LINE - 1)) and (LINE_COUNT <= 18)) loop
  832.             READ_IN_LINE := EMPTY_STRING_156; 
  833.             GET_LINE(READ_IN_FILE, READ_IN_LINE, LAST_CHAR); 
  834.             if LAST_CHAR = 0 then 
  835.               BLANK_COUNT := BLANK_COUNT + 1; 
  836.             else 
  837.               BLANK_COUNT := 0; 
  838.             end if; 
  839.             if SAVING then 
  840.               PUT_LINE(SAVE_FILE, READ_IN_LINE(1 .. LAST_CHAR)); 
  841.             end if; 
  842.             CURRENT_LINE := CURRENT_LINE + 1; 
  843.  
  844.             --          don't need a SKIP_LINE statement.
  845.             if BLANK_COUNT < 3 then 
  846.               if (not (LAST_CHAR < 42 and LAST_CHAR > 0 and READ_IN_LINE(1 .. 30
  847.                 ) = BLANK_30)) then 
  848.  
  849.                 if LAST_CHAR > SCREEN_WIDTH then 
  850.                   LINE_COUNT := LINE_COUNT + 2; 
  851.                   PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => 
  852.                     READ_IN_LINE(1 .. SCREEN_WIDTH)); 
  853.                   PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => 
  854.                     READ_IN_LINE(SCREEN_WIDTH + 1 .. LAST_CHAR)); 
  855.                 else 
  856.                   PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => 
  857.                     READ_IN_LINE(1 .. LAST_CHAR)); 
  858.                   LINE_COUNT := LINE_COUNT + 1; 
  859.                 end if; 
  860.               end if; 
  861.             end if; 
  862.           end loop; 
  863.           if CURRENT_LINE >= (LAST_LINE - 1) then 
  864.             AT_LAST_LINE := TRUE; 
  865.           end if; 
  866.         end if; 
  867.  
  868.  
  869.       end if; 
  870.  
  871.       GOOD_ANSWER := FALSE; 
  872.       while not GOOD_ANSWER loop
  873.         GOOD_ANSWER := TRUE; 
  874.         if END_OF_FILE(READ_IN_FILE) or (AT_LAST_LINE) then 
  875.           READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => WAIT_STR, TIMEOUT
  876.             => 500, PROMPT_STRING => "     E[xit]   S[ave]   D[isplay again] "
  877.             , MAX_LENGTH => 1, RECEIVED_STRING_LENGTH => RECD_STR_LEN, 
  878.             TERMINATOR_CODE => TERM_CODE, DISPLAY_ID => VD_2_ID); 
  879.         else 
  880.           READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => WAIT_STR, TIMEOUT
  881.             => 500, PROMPT_STRING => 
  882.             "     E[xit]   C[ontinue]   S[ave]   D[isplay again] ", MAX_LENGTH
  883.             => 1, RECEIVED_STRING_LENGTH => RECD_STR_LEN, TERMINATOR_CODE => 
  884.             TERM_CODE, DISPLAY_ID => VD_2_ID); 
  885.         end if; 
  886.         PUT_LINE(DISPLAY_ID => VD_2_ID, TEXT => "               "); 
  887.         case WAIT_STR(1) is 
  888.           when 'E' | ASCII.LC_E => 
  889.             LAST_COMMAND := EXIT_COMMAND; 
  890.             EXIT_NOW := TRUE; 
  891.             exit; 
  892.           when 'S' | ASCII.LC_S => 
  893.             LAST_COMMAND := SAVE; 
  894.             if not SAVING then 
  895.               if not IS_OPEN(SAVE_FILE) then 
  896.                 CREATE(SAVE_FILE, OUT_FILE, LRM_READER_SAVE_FILE_NAME); 
  897.               end if; 
  898.  
  899.               -- write citation title to file save_file.
  900.               PUT_LINE(SAVE_FILE, 
  901.                 "Chapter reference from Ada Language Reference Manual:"); 
  902.               for I in 1 .. 11 loop
  903.                 case CITATION_REQUESTED(I) is 
  904.                   when 'c' | 'C' => 
  905.                     PUT(SAVE_FILE, "Chapter "); 
  906.                   when 's' | 'S' => 
  907.                     PUT(SAVE_FILE, " Section "); 
  908.                   when 'v' | 'V' => 
  909.                     PUT(SAVE_FILE, '.'); 
  910.                   when 'p' | 'P' => 
  911.                     PUT(SAVE_FILE, " Paragraph "); 
  912.                   when ' ' => 
  913.                     null; 
  914.                   when others => 
  915.                     PUT(SAVE_FILE, CITATION_REQUESTED(I)); 
  916.                 end case; 
  917.               end loop; 
  918.               NEW_LINE(SAVE_FILE, 3); 
  919.  
  920.               -- write citation title to file save_file.
  921.               SAVING := TRUE; 
  922.               if CURRENT_LINE > FIRST_LINE then 
  923.                 GOTO_FIRST_LINE(FIRST_LINE); 
  924.                 for I in FIRST_LINE .. (CURRENT_LINE) loop
  925.                   READ_IN_LINE := EMPTY_STRING_156; 
  926.                   GET_LINE(READ_IN_FILE, READ_IN_LINE, LAST_CHAR); 
  927.                   PUT_LINE(SAVE_FILE, READ_IN_LINE(1 .. LAST_CHAR)); 
  928.                 end loop; 
  929.               end if; 
  930.             end if; 
  931.           when 'D' | ASCII.LC_D => 
  932.             LAST_COMMAND := DISPLAY_AGAIN; 
  933.             GOTO_FIRST_LINE(FIRST_LINE); 
  934.             CURRENT_LINE := FIRST_LINE - 1; 
  935.             PUT_LINE(DISPLAY_ID => TEXT_SCREEN_DISPLAY, TEXT => "      "); 
  936.           when 'C' | ASCII.LC_C => 
  937.             LAST_COMMAND := CONTINUE; 
  938.             null; 
  939.  
  940.           -- continue the display
  941.           when others => 
  942.             GOOD_ANSWER := FALSE; 
  943.         end case; 
  944.  
  945.       -- while not good_answer loop
  946.       end loop; 
  947.  
  948.     --  while not eof(read_in_file) loop
  949.     end loop; 
  950.  
  951.  
  952.     if SAVING then 
  953.       NEW_LINE(SAVE_FILE, 3); 
  954.     end if; 
  955.     CLOSE(READ_IN_FILE); 
  956.     UNPASTE_VIRTUAL_DISPLAY(TEXT_SCREEN_DISPLAY, TERM_ID); 
  957.     REPASTE_VIRTUAL_DISPLAY(VD_2_ID, TERM_ID, 22, 2, CHAPTER_MENU_DISPLAY); 
  958.  
  959.  
  960.   end SCROLL_CHAP; 
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969. ------------------------------------------------------------------------------
  970.  
  971.  
  972. ------------------------------------------------------------------------------
  973.  
  974.  
  975.   function EXTRACT_SECTION(CITATION : in STRING) return INTEGER is 
  976.  
  977.   --perhaps global
  978.   --  Extract integer part of section number from citation.
  979.  
  980.     FOUND         : BOOLEAN := FALSE; 
  981.     I             : INTEGER; 
  982.     FIRST_SECTION : INTEGER := 0; 
  983.     LAST_SECTION  : INTEGER := 0; 
  984.  
  985.   begin
  986.     I := 3; 
  987.     loop
  988.       case CITATION(I) is 
  989.         when 's' | 'S' => 
  990.           FIRST_SECTION := I + 1; 
  991.         when 'v' | 'V' | 'p' | 'P' => 
  992.           LAST_SECTION := I - 1; 
  993.           FOUND := TRUE; 
  994.         when others => 
  995.           null; 
  996.       end case; 
  997.       if I = 11 then 
  998.         exit; 
  999.       else 
  1000.         I := I + 1; 
  1001.       end if; 
  1002.       exit when FOUND; 
  1003.     end loop; 
  1004.     if not FOUND then 
  1005.       for I in reverse 1 .. 11 loop
  1006.         if CITATION(I) /= ' ' then 
  1007.           LAST_SECTION := I; 
  1008.           FOUND := TRUE; 
  1009.           exit when FOUND; 
  1010.         end if; 
  1011.       end loop; 
  1012.     end if; 
  1013.  
  1014.     return INTEGER'VALUE(CITATION(FIRST_SECTION .. LAST_SECTION)); 
  1015.   end EXTRACT_SECTION; 
  1016.  
  1017.  
  1018.  
  1019.  
  1020. ------------------------------------------------------------------------------
  1021.  
  1022.   function EXTRACT_CHAPTER(CITATION : in STRING) return INTEGER is 
  1023.  
  1024.   --perhaps global
  1025.   --  Extract chapter from citation.
  1026.  
  1027.     FOUND     : BOOLEAN := FALSE; 
  1028.     I         : INTEGER; 
  1029.     LAST_CHAP : INTEGER := 0; 
  1030.  
  1031.   begin
  1032.     I := 2; 
  1033.     loop
  1034.       case CITATION(I) is 
  1035.         when 'p' | 'P' | 's' | 'S' => 
  1036.           LAST_CHAP := I - 1; 
  1037.           FOUND := TRUE; 
  1038.         when others => 
  1039.           null; 
  1040.       end case; 
  1041.       if I = 11 then 
  1042.         exit; 
  1043.       else 
  1044.         I := I + 1; 
  1045.       end if; 
  1046.       exit when FOUND; 
  1047.     end loop; 
  1048.     if not FOUND then 
  1049.       for I in reverse 1 .. 11 loop
  1050.         if CITATION(I) /= ' ' then 
  1051.           LAST_CHAP := I; 
  1052.           FOUND := TRUE; 
  1053.           exit when FOUND; 
  1054.         end if; 
  1055.       end loop; 
  1056.     end if; 
  1057.  
  1058.     return INTEGER'VALUE(CITATION(2 .. LAST_CHAP)); 
  1059.   end EXTRACT_CHAPTER; 
  1060.  
  1061.  
  1062. ------------------------------------------------------------------------------
  1063.  
  1064.   procedure GET_NEXT_SECTION_NUMBER(NEXT_SECTION         : in out STRING; 
  1065.                                     CHAPTER_MENU_DISPLAY : in LONGWORD_UNSIGNED
  1066.                                       ; 
  1067.                                     LAST_LINE            : in out NATURAL; 
  1068.                                     UNTIL_EOF            : in out BOOLEAN; 
  1069.                                     SUBSECTION           : in BOOLEAN) is 
  1070.  
  1071.   --perhaps global
  1072.  
  1073.     ORIGINAL_CHAPTER : INTEGER;  -- chapter part of requested chapter reference
  1074.     ORIGINAL_SECTION : INTEGER; -- integer part of section of requested chapter reference
  1075.     CURRENT_CHAPTER  : INTEGER; 
  1076.     CURRENT_SECTION  : INTEGER; 
  1077.     -- integer part of section of requested chapter reference
  1078.     NOT_PARAGRAPH    : BOOLEAN; 
  1079.     NS               : LEGAL_CITATIONS; 
  1080.     CITATION_STRING  : STRING(1 .. 11); 
  1081.  
  1082.  
  1083.   begin
  1084.     LAST_LINE := 0; 
  1085.     UNTIL_EOF := FALSE; 
  1086.     NS := LEGAL_CITATIONS'VALUE(NEXT_SECTION); 
  1087.     ORIGINAL_CHAPTER := EXTRACT_CHAPTER(NEXT_SECTION); 
  1088.     ORIGINAL_SECTION := EXTRACT_SECTION(NEXT_SECTION); 
  1089.     if SUBSECTION then 
  1090.       loop
  1091.         NOT_PARAGRAPH := TRUE; 
  1092.         if NS /= C14S7P3 then 
  1093.           NS := LEGAL_CITATIONS'SUCC(NS); 
  1094.         else 
  1095.           UNTIL_EOF := TRUE; 
  1096.           goto DISPLAY_REMAINDER_OF_FILE; 
  1097.         end if; 
  1098.  
  1099.         --        >>>>>> detect next chapter
  1100.         --
  1101.         --
  1102.         LEGAL_CITATIONS_IO.PUT(NEXT_SECTION, NS); 
  1103.         CURRENT_CHAPTER := EXTRACT_CHAPTER(NEXT_SECTION); 
  1104.         if CURRENT_CHAPTER > ORIGINAL_CHAPTER then 
  1105.           UNTIL_EOF := TRUE; 
  1106.           goto DISPLAY_REMAINDER_OF_FILE; 
  1107.         end if; 
  1108.         for I in reverse 1 .. 11 loop
  1109.           if ((NEXT_SECTION(I) = 'p') or (NEXT_SECTION(I) = 'P')) then 
  1110.             NOT_PARAGRAPH := FALSE; 
  1111.           end if; 
  1112.         end loop; 
  1113.         if NOT_PARAGRAPH then 
  1114.           exit; 
  1115.         end if; 
  1116.       end loop; 
  1117.     else 
  1118.       loop
  1119.         if NS /= C14S7P3 then 
  1120.           NS := LEGAL_CITATIONS'SUCC(NS); 
  1121.         else 
  1122.           UNTIL_EOF := TRUE; 
  1123.           goto DISPLAY_REMAINDER_OF_FILE; 
  1124.         end if; 
  1125.         LEGAL_CITATIONS_IO.PUT(NEXT_SECTION, NS); 
  1126.         CURRENT_CHAPTER := EXTRACT_CHAPTER(NEXT_SECTION); 
  1127.         if CURRENT_CHAPTER > ORIGINAL_CHAPTER then 
  1128.           UNTIL_EOF := TRUE; 
  1129.           goto DISPLAY_REMAINDER_OF_FILE; 
  1130.         else 
  1131.           CURRENT_SECTION := EXTRACT_SECTION(NEXT_SECTION); 
  1132.           if CURRENT_SECTION > ORIGINAL_SECTION then 
  1133.             UNTIL_EOF := FALSE; 
  1134.             LAST_LINE := CHAP_POINTERS(NS); 
  1135.             exit; 
  1136.           end if; 
  1137.         end if; 
  1138.       end loop; 
  1139.  
  1140.     -- if subsection
  1141.     end if; 
  1142.  
  1143.     <<DISPLAY_REMAINDER_OF_FILE>> null; 
  1144.  
  1145.     if not UNTIL_EOF then 
  1146.       LAST_LINE := CHAP_POINTERS(NS); 
  1147.     end if; 
  1148.   end GET_NEXT_SECTION_NUMBER; 
  1149.  
  1150. ------------------------------------------------------------------------------
  1151.  
  1152.  
  1153.   procedure DO_CHAPTER_MENU(SAVE_FILE : in out FILE_TYPE) is 
  1154.  
  1155.  
  1156.     ALL_CHAPTER                   : BOOLEAN := FALSE; 
  1157.     ALL_SECTION                   : BOOLEAN := FALSE; 
  1158.     CHAP_FILENAME                 : STRING(1 .. 18); 
  1159.     CHAPTER_CHOICE                : STRING(1 .. 3); 
  1160.     CHAPTER_CHOICE_INT            : INTEGER; 
  1161.     CHAPTER_CHOICE_LEN            : WORD_UNSIGNED; 
  1162.     CHAPTER_CHOICE_LEN_INT        : INTEGER; 
  1163.     CITATION_REQUESTED            : STRING(1 .. 11) := "c1p1       "; 
  1164.     CITATION_REQUESTED_LENGTH     : NATURAL; 
  1165.     CITATION_TO_GET               : LEGAL_CITATIONS := C1P1; 
  1166.     CITATION_MARKER               : LEGAL_CITATIONS := C1P1; 
  1167.     EXIT_CHAPTER_LOOP             : BOOLEAN; 
  1168.     EXIT_CHOICE                   : STRING(1 .. 1); 
  1169.     EXIT_CHOICE_LEN               : WORD_UNSIGNED; 
  1170.     FIRST_LINE                    : NATURAL := 0; 
  1171.     FIRST_TIME_THROUGH_OUTER_LOOP : BOOLEAN := TRUE; 
  1172.     GOOD_ANSWER                   : BOOLEAN; 
  1173.     I                             : INTEGER :=  -1; 
  1174.     LAST_LINE                     : NATURAL := 0; 
  1175.     NEXT_CITATION                 : STRING(1 .. 11); 
  1176.     NEXT_CITATION_LENGTH          : NATURAL; 
  1177.     NONEXISTENT_CITATION_MESSAGE  : STRING(1 .. 78); 
  1178.     NONEXISTENT_CITATION_REPLY    : STRING(1 .. 2); 
  1179.     NONEXISTENT_CITATION_LEN      : WORD_UNSIGNED; 
  1180.     PARAGRAPH_CHOICE              : STRING(1 .. 2); 
  1181.     PARAGRAPH_CHOICE_LEN          : WORD_UNSIGNED; 
  1182.     PARAGRAPH_CHOICE_LEN_INT      : INTEGER; 
  1183.     PLACE                         : NATURAL := 0; 
  1184.     REQUEST_LENGTH                : NATURAL := 2; 
  1185.     SECTION_BEGIN, SECTION_END    : NATURAL := 0; 
  1186.     SECTION_CHOICE                : STRING(1 .. 5); 
  1187.     SECTION_CHOICE_LEN            : WORD_UNSIGNED; 
  1188.     SECTION_CHOICE_LEN_INT        : INTEGER; 
  1189.     SUBSECTION                    : BOOLEAN; 
  1190.     TERM_CODE                     : WORD_UNSIGNED; 
  1191.     UNTIL_EOF                     : BOOLEAN := FALSE; 
  1192.     C1                            : STRING(1 .. 3); 
  1193.     C2                            : INTEGER; 
  1194.     ROW, COL                      : INTEGER; 
  1195.     DUMP_FILE                     : FILE_TYPE; 
  1196.  
  1197.     ---------------------------------------
  1198.  
  1199.     function CHAPTER_NUMBER(CHAP     : in STRING; 
  1200.                             CHAP_LEN : in WORD_UNSIGNED) return INTEGER is 
  1201.       I          : INTEGER; 
  1202.       CHAP_LEN_I : INTEGER; 
  1203.       TEMP       : INTEGER := 0; 
  1204.     begin
  1205.       CHAP_LEN_I := INTEGER(CHAP_LEN); 
  1206.       if CHAP_LEN_I > 0 then 
  1207.         TEMP := INTEGER'VALUE(CHAP(1 .. CHAP_LEN_I)); 
  1208.       else 
  1209.         TEMP := 0; 
  1210.       end if; 
  1211.       return TEMP; 
  1212.     end CHAPTER_NUMBER; 
  1213.  
  1214.     ---------------------------------------
  1215.  
  1216.  
  1217.     function VALID_CHAPTER(CHAP : in INTEGER) return BOOLEAN is 
  1218.     --perhaps global
  1219.       TEMP_RESULT : BOOLEAN; 
  1220.     begin
  1221.       case CHAP is 
  1222.         when 1 .. 14 => 
  1223.           TEMP_RESULT := TRUE; 
  1224.         when others => 
  1225.           TEMP_RESULT := FALSE; 
  1226.       end case; 
  1227.       return TEMP_RESULT; 
  1228.     end VALID_CHAPTER; 
  1229.  
  1230.     ---------------------------------------
  1231.  
  1232.     procedure GET_CITATION_FROM_USER is 
  1233.     -- local -- term_code
  1234.     -- parameter -- chapter_choice_int
  1235.     begin
  1236.       CHAPTER_CHOICE := "   "; 
  1237.       SECTION_CHOICE := "     "; 
  1238.       PARAGRAPH_CHOICE := "  "; 
  1239.  
  1240.       ERASE_CHARS(CHAPTER_MENU_DISPLAY, 30, 16, 1); 
  1241.       ERASE_CHARS(CHAPTER_MENU_DISPLAY, 30, 17, 1); 
  1242.       ERASE_CHARS(CHAPTER_MENU_DISPLAY, 45, 18, 1); 
  1243.       SET_CURSOR_ABS(CHAPTER_MENU_DISPLAY, 16, 1); 
  1244.       READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => CHAPTER_CHOICE, 
  1245.         MAX_LENGTH => 3, RECEIVED_STRING_LENGTH => CHAPTER_CHOICE_LEN, 
  1246.         PROMPT_STRING => " Enter chapter, please: ", TIMEOUT => 90, 
  1247.         TERMINATOR_CODE => TERM_CODE, DISPLAY_ID => CHAPTER_MENU_DISPLAY); 
  1248.       READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => SECTION_CHOICE, 
  1249.         MAX_LENGTH => 5, RECEIVED_STRING_LENGTH => SECTION_CHOICE_LEN, 
  1250.         PROMPT_STRING => "               section: ", TERMINATOR_CODE => 
  1251.         TERM_CODE, DISPLAY_ID => CHAPTER_MENU_DISPLAY); 
  1252.       READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => PARAGRAPH_CHOICE, 
  1253.         MAX_LENGTH => 3, RECEIVED_STRING_LENGTH => PARAGRAPH_CHOICE_LEN, 
  1254.         PROMPT_STRING => "             paragraph: ", TERMINATOR_CODE => 
  1255.         TERM_CODE, DISPLAY_ID => CHAPTER_MENU_DISPLAY); 
  1256.       CHAPTER_CHOICE_INT := CHAPTER_NUMBER(CHAPTER_CHOICE, CHAPTER_CHOICE_LEN); 
  1257.       if VALID_CHAPTER(CHAPTER_CHOICE_INT) then 
  1258.         GOOD_ANSWER := TRUE; 
  1259.       end if; 
  1260.       SET_CURSOR_ABS(CHAPTER_MENU_DISPLAY, 20, 1); 
  1261.     end GET_CITATION_FROM_USER; 
  1262.  
  1263.     ---------------------------------------
  1264.  
  1265.     procedure COMBINE_STRINGS_INTO_IMAGE_FORM is 
  1266.     --perhaps global
  1267.     -- local -- place, request_length, section_begin, section_end
  1268.     begin
  1269.       CITATION_REQUESTED := "           "; 
  1270.       CITATION_REQUESTED_LENGTH := 0; 
  1271.       CHAPTER_CHOICE_LEN_INT := INTEGER(CHAPTER_CHOICE_LEN); 
  1272.       SECTION_CHOICE_LEN_INT := INTEGER(SECTION_CHOICE_LEN); 
  1273.       PARAGRAPH_CHOICE_LEN_INT := INTEGER(PARAGRAPH_CHOICE_LEN); 
  1274.       CITATION_REQUESTED(1) := 'C'; 
  1275.       CITATION_REQUESTED(2 .. 2) := CHAPTER_CHOICE(1 .. 1); 
  1276.       CITATION_REQUESTED(2 .. (CHAPTER_CHOICE_LEN_INT + 1)) := CHAPTER_CHOICE(1
  1277.         .. CHAPTER_CHOICE_LEN_INT); 
  1278.       PLACE := CHAPTER_CHOICE_LEN_INT + 2; 
  1279.       REQUEST_LENGTH := PLACE - 1; 
  1280.       if (SECTION_CHOICE_LEN_INT > 0) then 
  1281.         CITATION_REQUESTED(PLACE) := 'S'; 
  1282.         SECTION_BEGIN := PLACE + 1; 
  1283.         for I in 1 .. SECTION_CHOICE_LEN_INT loop
  1284.           if SECTION_CHOICE(I) = '.' then 
  1285.             CITATION_REQUESTED(PLACE + I) := 'v'; 
  1286.             SUBSECTION := TRUE; 
  1287.           else 
  1288.             CITATION_REQUESTED(PLACE + I) := SECTION_CHOICE(I); 
  1289.           end if; 
  1290.         end loop; 
  1291.         SECTION_END := SECTION_BEGIN + SECTION_CHOICE_LEN_INT - 1; 
  1292.         PLACE := PLACE + SECTION_CHOICE_LEN_INT + 1; 
  1293.         REQUEST_LENGTH := PLACE - 1; 
  1294.         if PARAGRAPH_CHOICE_LEN_INT <= 0 then 
  1295.           ALL_SECTION := TRUE; 
  1296.         end if; 
  1297.       else 
  1298.         if PARAGRAPH_CHOICE_LEN_INT <= 0 then 
  1299.           ALL_CHAPTER := TRUE; 
  1300.         end if; 
  1301.       end if; 
  1302.  
  1303.       -- if section_choice_len_int > 0
  1304.       if (PARAGRAPH_CHOICE_LEN_INT > 0) then 
  1305.         CITATION_REQUESTED(PLACE) := 'P'; 
  1306.         CITATION_REQUESTED((PLACE + 1) .. (PLACE + PARAGRAPH_CHOICE_LEN_INT))
  1307.           := PARAGRAPH_CHOICE(1 .. PARAGRAPH_CHOICE_LEN_INT); 
  1308.         REQUEST_LENGTH := PLACE + PARAGRAPH_CHOICE_LEN_INT; 
  1309.       end if; 
  1310.  
  1311.     -- if paragraph_choice_len_int > 0
  1312.     end COMBINE_STRINGS_INTO_IMAGE_FORM; 
  1313.  
  1314.     ---------------------------------------
  1315.  
  1316.     procedure FILL_IN_CHAPTER_FILENAME(CHAP_FILENAME      : out STRING; 
  1317.                                        CHAPTER_CHOICE_INT : in INTEGER) is 
  1318.  
  1319.       TEMP_CHAP_FILENAME : STRING(1 .. 10) := "chap  .doc"; 
  1320.       TEMP_LENGTH        : NATURAL; 
  1321.  
  1322.       --perhaps global
  1323.     begin
  1324.       if CHAPTER_CHOICE_INT in 1 .. 14 then 
  1325.         case CHAPTER_CHOICE_INT is 
  1326.           when 1 => 
  1327.             TEMP_CHAP_FILENAME(5 .. 6) := "01"; 
  1328.           when 2 => 
  1329.             TEMP_CHAP_FILENAME(5 .. 6) := "02"; 
  1330.           when 3 => 
  1331.             TEMP_CHAP_FILENAME(5 .. 6) := "03"; 
  1332.           when 4 => 
  1333.             TEMP_CHAP_FILENAME(5 .. 6) := "04"; 
  1334.           when 5 => 
  1335.             TEMP_CHAP_FILENAME(5 .. 6) := "05"; 
  1336.           when 6 => 
  1337.             TEMP_CHAP_FILENAME(5 .. 6) := "06"; 
  1338.           when 7 => 
  1339.             TEMP_CHAP_FILENAME(5 .. 6) := "07"; 
  1340.           when 8 => 
  1341.             TEMP_CHAP_FILENAME(5 .. 6) := "08"; 
  1342.           when 9 => 
  1343.             TEMP_CHAP_FILENAME(5 .. 6) := "09"; 
  1344.           when 10 => 
  1345.             TEMP_CHAP_FILENAME(5 .. 6) := "10"; 
  1346.           when 11 => 
  1347.             TEMP_CHAP_FILENAME(5 .. 6) := "11"; 
  1348.           when 12 => 
  1349.             TEMP_CHAP_FILENAME(5 .. 6) := "12"; 
  1350.           when 13 => 
  1351.             TEMP_CHAP_FILENAME(5 .. 6) := "13"; 
  1352.           when 14 => 
  1353.             TEMP_CHAP_FILENAME(5 .. 6) := "14"; 
  1354.           when others => 
  1355.             null; 
  1356.         end case; 
  1357.  
  1358.         -- Length of CHAP_FILENAME := LRM_FILE_NAME_PREFIX_LENGTH
  1359.         -- + Length(TEMP_CHAP_FILENAME)
  1360.         TEMP_LENGTH := LRM_FILE_NAME_PREFIX_LENGTH + 10; 
  1361.         CHAP_FILENAME(1 .. TEMP_LENGTH) := LRM_FILE_NAME_PREFIX(1 .. 
  1362.           LRM_FILE_NAME_PREFIX_LENGTH) & TEMP_CHAP_FILENAME; 
  1363.       end if; 
  1364.     end FILL_IN_CHAPTER_FILENAME; 
  1365.  
  1366.     ---------------------------------------
  1367.  
  1368.     procedure VALIDATE_CITATION(CITATION_REQUESTED : in STRING; 
  1369.                                 REQUEST_LENGTH     : in NATURAL; 
  1370.                                 CITATION_TO_GET    : out LEGAL_CITATIONS) is 
  1371.     --perhaps global
  1372.     begin
  1373.  
  1374.       CITATION_TO_GET := LEGAL_CITATIONS'VALUE(CITATION_REQUESTED(1 .. 
  1375.         REQUEST_LENGTH)); 
  1376.  
  1377.     end VALIDATE_CITATION; 
  1378.  
  1379.  
  1380.  
  1381.     ------------------------------------------------------------
  1382.     --              do_chapter_menu_smg  body
  1383.     ------------------------------------------------------------
  1384.  
  1385.  
  1386.     --do_chapter_menu_smg
  1387.   begin
  1388.  
  1389.  
  1390.     PASTE_VIRTUAL_DISPLAY(CHAPTER_MENU_DISPLAY, TERM_ID, LEFT_MOST, TOP_MOST); 
  1391.     EXIT_CHAPTER_LOOP := FALSE; 
  1392.  
  1393.     loop
  1394.  
  1395.       -- block for exception CONSTRAINT_ERROR
  1396.       begin
  1397.         if not FIRST_TIME_THROUGH_OUTER_LOOP then 
  1398.           SET_CURSOR_ABS(CHAPTER_MENU_DISPLAY, 1, 1); 
  1399.           READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => EXIT_CHOICE, 
  1400.             MAX_LENGTH => 1, PROMPT_STRING => 
  1401.             "Do you want to leave the Chapter Menu now? ", TERMINATOR_CODE => 
  1402.             TERM_CODE, DISPLAY_ID => CHAPTER_MENU_DISPLAY, 
  1403.             RECEIVED_STRING_LENGTH => EXIT_CHOICE_LEN); 
  1404.           ERASE_CHARS(CHAPTER_MENU_DISPLAY, 45, 1, 1); 
  1405.           case EXIT_CHOICE(1) is 
  1406.             when 'y' | 'Y' => 
  1407.               EXIT_CHAPTER_LOOP := TRUE; 
  1408.             when others => 
  1409.               null; 
  1410.           end case; 
  1411.         end if; 
  1412.  
  1413.         FIRST_TIME_THROUGH_OUTER_LOOP := FALSE; 
  1414.         exit when EXIT_CHAPTER_LOOP; 
  1415.  
  1416.  
  1417.         ERASE_CHARS(CHAPTER_MENU_DISPLAY, 30, 17, 1); 
  1418.  
  1419.         GOOD_ANSWER := FALSE; 
  1420.         while not GOOD_ANSWER loop
  1421.           GET_CITATION_FROM_USER; 
  1422.         end loop; 
  1423.  
  1424.         -- Combine the contents of strings chapter_choice, section_choice
  1425.         --   and paragraph_choice into one string in the same format as
  1426.         --   the enumerated type legal_citations.
  1427.         SUBSECTION := FALSE; 
  1428.         COMBINE_STRINGS_INTO_IMAGE_FORM; 
  1429.  
  1430.         -- Here we have at least a valid chapter.
  1431.         -- See if its a legal citation.
  1432.         -- If its NOT a legal citation, will raise exception constraint_error,
  1433.         --   perform exception block (when constraint_error), and
  1434.         --   exit procedure do_chapter_menu_smg.
  1435.  
  1436.         VALIDATE_CITATION(CITATION_REQUESTED, REQUEST_LENGTH, CITATION_TO_GET); 
  1437.  
  1438.         FILL_IN_CHAPTER_FILENAME(CHAP_FILENAME, CHAPTER_CHOICE_INT); 
  1439.         FIRST_LINE := CHAP_POINTERS(CITATION_TO_GET); 
  1440.  
  1441.  
  1442.         if PARAGRAPH_CHOICE_LEN_INT > 0 then 
  1443.           LAST_LINE := CHAP_POINTERS(LEGAL_CITATIONS'SUCC(CITATION_TO_GET)); 
  1444.           SCROLL_CHAP(CHAP_FILENAME, FIRST_LINE, LAST_LINE, SAVE_FILE, FALSE, 
  1445.             CITATION_REQUESTED); 
  1446.         else 
  1447.           if SECTION_CHOICE_LEN_INT <= 0 then 
  1448.           -----entire chapter
  1449.             SCROLL_CHAP(CHAP_FILENAME, FIRST_LINE, 0, SAVE_FILE, TRUE, 
  1450.               CITATION_REQUESTED); 
  1451.           else 
  1452.             NEXT_CITATION := CITATION_REQUESTED; 
  1453.             GET_NEXT_SECTION_NUMBER(NEXT_CITATION, CHAPTER_MENU_DISPLAY, 
  1454.               LAST_LINE, UNTIL_EOF, SUBSECTION); 
  1455.             SCROLL_CHAP(CHAP_FILENAME, FIRST_LINE, LAST_LINE, SAVE_FILE, 
  1456.               UNTIL_EOF, CITATION_REQUESTED); 
  1457.           end if; 
  1458.         end if; 
  1459.  
  1460.         -- erase error message from nonexistent citation
  1461.         ERASE_CHARS(CHAPTER_MENU_DISPLAY, 60, 21, 1); 
  1462.         ERASE_CHARS(CHAPTER_MENU_DISPLAY, 60, 22, 1); 
  1463.  
  1464.       exception
  1465.         when CONSTRAINT_ERROR => 
  1466.           SET_CURSOR_ABS(CHAPTER_MENU_DISPLAY, 20, 1); 
  1467.           NONEXISTENT_CITATION_MESSAGE := (others => ' '); 
  1468.           NONEXISTENT_CITATION_MESSAGE(1 .. 7) := "Chapter"; 
  1469.           NONEXISTENT_CITATION_MESSAGE(9 .. (8 + CHAPTER_CHOICE_LEN_INT)) := 
  1470.             CHAPTER_CHOICE(1 .. CHAPTER_CHOICE_LEN_INT); 
  1471.           PLACE := 10 + CHAPTER_CHOICE_LEN_INT; 
  1472.           if SECTION_CHOICE_LEN_INT > 0 then 
  1473.             NONEXISTENT_CITATION_MESSAGE(PLACE .. PLACE + 6) := "Section"; 
  1474.             PLACE := PLACE + 8; 
  1475.             NONEXISTENT_CITATION_MESSAGE(PLACE .. (PLACE + 
  1476.               SECTION_CHOICE_LEN_INT - 1)) := SECTION_CHOICE(1 .. 
  1477.               SECTION_CHOICE_LEN_INT); 
  1478.             PLACE := PLACE + SECTION_CHOICE_LEN_INT + 1; 
  1479.           end if; 
  1480.           if PARAGRAPH_CHOICE_LEN_INT > 0 then 
  1481.             NONEXISTENT_CITATION_MESSAGE(PLACE .. PLACE + 8) := "Paragraph"; 
  1482.             PLACE := PLACE + 10; 
  1483.             NONEXISTENT_CITATION_MESSAGE(PLACE .. (PLACE + 
  1484.               PARAGRAPH_CHOICE_LEN_INT - 1)) := PARAGRAPH_CHOICE(1 .. 
  1485.               PARAGRAPH_CHOICE_LEN_INT); 
  1486.             PLACE := PLACE + PARAGRAPH_CHOICE_LEN_INT + 1; 
  1487.           end if; 
  1488.           NONEXISTENT_CITATION_MESSAGE(PLACE .. PLACE + 24) := 
  1489.             "is not a valid reference."; 
  1490.           PUT_LINE(DISPLAY_ID => CHAPTER_MENU_DISPLAY, TEXT => 
  1491.             NONEXISTENT_CITATION_MESSAGE); 
  1492.           -- Display "Please try again " message for 15 seconds.
  1493.           READ_STRING(KEYBOARD_ID => KB_ID, RECEIVED_TEXT => 
  1494.             NONEXISTENT_CITATION_REPLY, MAX_LENGTH => 1, PROMPT_STRING => 
  1495.             "  Please try again. ", TERMINATOR_CODE => TERM_CODE, DISPLAY_ID => 
  1496.             CHAPTER_MENU_DISPLAY, RECEIVED_STRING_LENGTH => 
  1497.             NONEXISTENT_CITATION_LEN, TIMEOUT => 15); 
  1498.  
  1499.           -- end of block for exception CONSTRAINT_ERROR
  1500.       end; 
  1501.  
  1502.     end loop; 
  1503.  
  1504.     UNPASTE_VIRTUAL_DISPLAY(CHAPTER_MENU_DISPLAY, TERM_ID); 
  1505.  
  1506.   end DO_CHAPTER_MENU; 
  1507.  
  1508. ------------------------------------------------------------------------------
  1509. end LRM_SMG; 
  1510.  
  1511. ------------------------------------------------------------------------------
  1512.